/**
 * Copyright(C) 2008 Matthias Braunhofer
 * All rights reserved
 *
 * Created on: 07.09.2008
 */

package it.cums.printing;

import java.util.Date;
import java.util.List;

import it.cums.model.Customer;
import it.cums.model.Invoice;
import it.cums.model.Order;
import it.cums.model.OrderedProduct;
import it.cums.model.Product;
import it.cums.model.Supplier;
import it.cums.util.Converter;
import it.cums.util.InvoiceManager;
import it.cums.util.OrderedProductManager;

import net.sf.paperclips.DefaultGridLook;
import net.sf.paperclips.GridLook;
import net.sf.paperclips.GridPrint;
import net.sf.paperclips.LinePrint;
import net.sf.paperclips.PageDecoration;
import net.sf.paperclips.PageNumber;
import net.sf.paperclips.PageNumberPrint;
import net.sf.paperclips.PagePrint;
import net.sf.paperclips.Print;
import net.sf.paperclips.SimplePageDecoration;
import net.sf.paperclips.TextPrint;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.FontData;

public class PrintingDesign {
	
    public static PagePrint createPrint(Object object) {
        DefaultGridLook look = new DefaultGridLook();
        look.setCellSpacing(5, 2);
        GridPrint grid = new GridPrint("p:g, d:g", look);
        final FontData bold = new FontData("Arial", 10, SWT.BOLD);
        final FontData normal = new FontData("Arial", 10, SWT.NORMAL);
        if (object instanceof Customer) {
        	prepareCustomerData((Customer)object, grid, bold, normal);
        } else if (object instanceof Product) {
        	prepareProductData((Product)object, grid, bold, normal);
        } else if (object instanceof Supplier) {
        	prepareSupplierData((Supplier)object, grid, bold, normal);
        } else if (object instanceof Order) {
        	prepareOrderData((Order)object, grid, bold, normal);
        } else if (object instanceof Invoice) {
        	prepareInvoiceData((Invoice)object, grid, bold, normal);
        }
        PagePrint page = new PagePrint(grid);
        page.setHeader(new SimplePageDecoration(new TextPrint(object.toString(), SWT.CENTER)));
        PageDecoration footer = new PageDecoration() {
            private final GridLook footerLook = new DefaultGridLook(5, 2);
            
            public Print createPrint(PageNumber pageNumber) {
              GridPrint grid = new GridPrint("d:g, d", this.footerLook);
              grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER);
              PageNumberPrint pageNumberPrint = new PageNumberPrint(pageNumber, normal);
              pageNumberPrint.setAlign(SWT.CENTER);
              grid.add(pageNumberPrint);
              return grid;
            }
          };
        page.setFooter(footer);
        page.setHeaderGap(5);
        page.setFooterGap(2);

        return page;
    }
    
    private static void prepareInvoiceData(Invoice invoice, GridPrint grid, FontData bold, FontData normal) {
    	//header
    	grid.add(new TextPrint("\nOverview", bold), GridPrint.REMAINDER);
    	
    	//invoice number
    	grid.add(new TextPrint("Invoice number:", bold));
    	grid.add(new TextPrint(String.valueOf(invoice.getId()), normal));
    	
    	//creation date
    	grid.add(new TextPrint("Creation date:", bold));
    	grid.add(new TextPrint(Converter.convertToString(new Date()), normal));
    	
    	//header
    	grid.add(new TextPrint("\nCustomer", bold), GridPrint.REMAINDER);
    	
    	//name
    	grid.add(new TextPrint("Name:", bold));
    	grid.add(new TextPrint(invoice.getOrder().getCustomer().getName(), normal));
    	
    	//address
    	grid.add(new TextPrint("Address:", bold));
    	grid.add(new TextPrint(invoice.getOrder().getCustomer().getAddress(), normal));
    	
    	//location
    	grid.add(new TextPrint("Location:", bold));
    	grid.add(new TextPrint(invoice.getOrder().getCustomer().getCap() + " " + invoice.getOrder().getCustomer().getLocation() + " (" + invoice.getOrder().getCustomer().getCountry().getDescription().toUpperCase() + ")", normal));
	
    	//tax number
    	grid.add(new TextPrint("Tax number:", bold));
    	grid.add(new TextPrint(invoice.getOrder().getCustomer().getTaxNumber(), normal));
    	
    	//line
    	grid.add(new TextPrint("\n\n ", normal), GridPrint.REMAINDER);
    	grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER);
    	
    	//total amount
    	FontData largeBold = new FontData("Arial", 16, SWT.BOLD);
    	grid.add(new TextPrint("The invoice amount of:", bold));
        grid.add(new TextPrint(invoice.getAmount() + " Euro", largeBold));
        
        //due date
        grid.add(new TextPrint("has to paid until:", bold));
        grid.add(new TextPrint(Converter.convertToString(invoice.getDueDate()), largeBold));
        
        //condition / type
        grid.add(new TextPrint("with the following conditions:", bold));
        grid.add(new TextPrint(invoice.getType() + " / " + invoice.getCondition(), largeBold));
        
        //line
        grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER);
        grid.add(new TextPrint("\n ", normal), GridPrint.REMAINDER);
        
        //header
		grid.add(new TextPrint("\nOrder details", bold), GridPrint.REMAINDER);
    	
		//order date
        grid.add(new TextPrint("Order date:", bold));
        grid.add(new TextPrint(Converter.convertToString(invoice.getOrder().getOrderDate()), normal));
        
        //total price
        grid.add(new TextPrint("Total price (Euro):", bold));
        grid.add(new TextPrint(String.valueOf(invoice.getOrder().getTotalPrice()), normal));
        
        //discount
        grid.add(new TextPrint("Discount (%)", bold));
        grid.add(new TextPrint(String.valueOf(invoice.getOrder().getDiscount()), normal));
        
        //end price
        grid.add(new TextPrint("End price (Euro):", bold));
        grid.add(new TextPrint(String.valueOf(invoice.getOrder().getEndPrice()), normal));
        
      	//header
		grid.add(new TextPrint("\nProducts", bold), GridPrint.REMAINDER);
		
		DefaultGridLook look = new DefaultGridLook();
        look.setCellSpacing(5, 2);
		GridPrint gridProductsPrint = new GridPrint("d:g, d:g, d:g, d:g, d:g, d:g", look);
		
		//column headers
		gridProductsPrint.add(new TextPrint("Product", bold));
		gridProductsPrint.add(new TextPrint("Price (Euro)", bold));
		gridProductsPrint.add(new TextPrint("Quantity", bold));
		gridProductsPrint.add(new TextPrint("Total price (Euro)", bold));
		gridProductsPrint.add(new TextPrint("Discount (%)", bold));
		gridProductsPrint.add(new TextPrint("End price (Euro)", bold));
		
		//ordered products
		List<OrderedProduct> products = OrderedProductManager.getInstance().listOrderedProducts(invoice.getOrder());
		for (OrderedProduct orderedProduct : products) {
			gridProductsPrint.add(new TextPrint(orderedProduct.getProduct(), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getPrice()), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getQuantity()), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getTotalPrice()), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getDiscount()), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getEndPrice()), normal));
		}   
		
		grid.add(gridProductsPrint, 2);
    }

	private static void prepareOrderData(Order order, GridPrint grid, FontData bold, FontData normal) {
    	//header
		grid.add(new TextPrint("\nOverview", bold), GridPrint.REMAINDER);
		
        //customer
        grid.add(new TextPrint("Customer:", bold));
        grid.add(new TextPrint(order.getCustomer().getName(), normal));
        
        //priority
        grid.add(new TextPrint("Priority:", bold));
        grid.add(new TextPrint(order.getPriority(), normal));
        
        //order date
        grid.add(new TextPrint("Order date:", bold));
        grid.add(new TextPrint(Converter.convertToString(order.getOrderDate()), normal));
        
        //delivery date
        grid.add(new TextPrint("Delivery date:", bold));
        grid.add(new TextPrint(Converter.convertToString(order.getDeliveryDate()), normal));
    
        //total price
        grid.add(new TextPrint("Total price (Euro):", bold));
        grid.add(new TextPrint(String.valueOf(order.getTotalPrice()), normal));
        
        //discount
        grid.add(new TextPrint("Discount (%)", bold));
        grid.add(new TextPrint(String.valueOf(order.getDiscount()), normal));
        
        //end price
        grid.add(new TextPrint("End price (Euro):", bold));
        grid.add(new TextPrint(String.valueOf(order.getEndPrice()), normal));
        
        //header
		grid.add(new TextPrint("\nProducts", bold), GridPrint.REMAINDER);
		
		DefaultGridLook look = new DefaultGridLook();
        look.setCellSpacing(5, 2);
		GridPrint gridProductsPrint = new GridPrint("d:g, d:g, d:g, d:g, d:g, d:g", look);
		
		//column headers
		gridProductsPrint.add(new TextPrint("Product", bold));
		gridProductsPrint.add(new TextPrint("Price (Euro)", bold));
		gridProductsPrint.add(new TextPrint("Quantity", bold));
		gridProductsPrint.add(new TextPrint("Total price (Euro)", bold));
		gridProductsPrint.add(new TextPrint("Discount (%)", bold));
		gridProductsPrint.add(new TextPrint("End price (Euro)", bold));
		
		//ordered products
		List<OrderedProduct> products = OrderedProductManager.getInstance().listOrderedProducts(order);
		for (OrderedProduct orderedProduct : products) {
			gridProductsPrint.add(new TextPrint(orderedProduct.getProduct(), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getPrice()), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getQuantity()), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getTotalPrice()), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getDiscount()), normal));
			gridProductsPrint.add(new TextPrint(String.valueOf(orderedProduct.getEndPrice()), normal));
		}
	
		grid.add(gridProductsPrint, 2);
		
		//header
		grid.add(new TextPrint("\nInvoices", bold), GridPrint.REMAINDER);
		
		GridPrint gridInvoicesPrint = new GridPrint("d:g, d:g, d:g, d:g, d:g, d:g", look);
		
		//column headers
		gridInvoicesPrint.add(new TextPrint("Due date", bold));
		gridInvoicesPrint.add(new TextPrint("Amount (Euro)", bold));
		gridInvoicesPrint.add(new TextPrint("Condition", bold));
		gridInvoicesPrint.add(new TextPrint("Type", bold));
		gridInvoicesPrint.add(new TextPrint("Status", bold));
		gridInvoicesPrint.add(new TextPrint("Payment date", bold));
		
		//invoices
		List<Invoice> invoices = InvoiceManager.getInstance().listInvoices(order);
		for (Invoice invoice : invoices) {
			gridInvoicesPrint.add(new TextPrint(Converter.convertToString(invoice.getDueDate()), normal));
			gridInvoicesPrint.add(new TextPrint(String.valueOf(invoice.getAmount()), normal));
			gridInvoicesPrint.add(new TextPrint(invoice.getCondition(), normal));
			gridInvoicesPrint.add(new TextPrint(invoice.getType(), normal));
			gridInvoicesPrint.add(new TextPrint(invoice.getStatus(), normal));
			gridInvoicesPrint.add(new TextPrint(Converter.convertToString(invoice.getPaymentDate()), normal));
		}
	
		grid.add(gridInvoicesPrint, 2);
    }

	private static void prepareSupplierData(Supplier supplier, GridPrint grid, FontData bold, FontData normal) {
		//header
		grid.add(new TextPrint("\nBasic information", bold), GridPrint.REMAINDER);
		
        //name
        grid.add(new TextPrint("Name:", bold));
        grid.add(new TextPrint(supplier.getName(), normal));
        
        //tax number
        grid.add(new TextPrint("Tax number:", bold));
        grid.add(new TextPrint(supplier.getTaxNumber(), normal));
        
        //reference person
        grid.add(new TextPrint("Reference person:", bold));
        grid.add(new TextPrint(supplier.getReferencePerson(), normal));
        
      	//header
		grid.add(new TextPrint("\nContact information", bold), GridPrint.REMAINDER);
		
		//address
		grid.add(new TextPrint("Address:", bold));
        grid.add(new TextPrint(supplier.getAddress(), normal));
        
        //CAP
        grid.add(new TextPrint("CAP:", bold));
        grid.add(new TextPrint(supplier.getCap(), normal));
        
        //location
        grid.add(new TextPrint("Location:", bold));
        grid.add(new TextPrint(supplier.getLocation(), normal));
		
        //country
        grid.add(new TextPrint("Country:", bold));
        grid.add(new TextPrint(supplier.getCountry().getDescription(), normal));
        
        //phone
        grid.add(new TextPrint("Phone:", bold));
        grid.add(new TextPrint(supplier.getPhone(), normal));
        
        //mobile phone
        grid.add(new TextPrint("Mobile phone:", bold));
        grid.add(new TextPrint(supplier.getMobilePhone(), normal));
        
        //email
        grid.add(new TextPrint("E-Mail:", bold));
        grid.add(new TextPrint(supplier.getEmail(), normal));
        
        //website
        grid.add(new TextPrint("Website:", bold));
        grid.add(new TextPrint(supplier.getWebSite(), normal));
        
      	//header
		grid.add(new TextPrint("\nAccount details", bold), GridPrint.REMAINDER);
		grid.add(new TextPrint(supplier.getAccountDetails(), normal), GridPrint.REMAINDER);
	    
        //header
		grid.add(new TextPrint("\nAdditional information", bold), GridPrint.REMAINDER);
		grid.add(new TextPrint(supplier.getNotes(), normal), GridPrint.REMAINDER);
	}

	private static void prepareCustomerData(Customer customer, GridPrint grid, FontData bold, FontData normal) {
		//header
		grid.add(new TextPrint("\nBasic information", bold), GridPrint.REMAINDER);
		
        //name
        grid.add(new TextPrint("Name:", bold));
        grid.add(new TextPrint(customer.getName(), normal));
        
        //tax number
        grid.add(new TextPrint("Tax number:", bold));
        grid.add(new TextPrint(customer.getTaxNumber(), normal));
        
        //reference person
        grid.add(new TextPrint("Reference person:", bold));
        grid.add(new TextPrint(customer.getReferencePerson(), normal));
        
        //header
		grid.add(new TextPrint("\nContact information", bold), GridPrint.REMAINDER);
		
		//address
		grid.add(new TextPrint("Address:", bold));
        grid.add(new TextPrint(customer.getAddress(), normal));
        
        //CAP
        grid.add(new TextPrint("CAP:", bold));
        grid.add(new TextPrint(customer.getCap(), normal));
        
        //location
        grid.add(new TextPrint("Location:", bold));
        grid.add(new TextPrint(customer.getLocation(), normal));
		
        //country
        grid.add(new TextPrint("Country:", bold));
        grid.add(new TextPrint(customer.getCountry().getDescription(), normal));
        
        //phone
        grid.add(new TextPrint("Phone:", bold));
        grid.add(new TextPrint(customer.getPhone(), normal));
        
        //mobile phone
        grid.add(new TextPrint("Mobile phone:", bold));
        grid.add(new TextPrint(customer.getMobilePhone(), normal));
        
        //email
        grid.add(new TextPrint("E-Mail:", bold));
        grid.add(new TextPrint(customer.getEmail(), normal));
        
        //website
        grid.add(new TextPrint("Website:", bold));
        grid.add(new TextPrint(customer.getWebSite(), normal));
        
      	//header
		grid.add(new TextPrint("\nDelivery information", bold), GridPrint.REMAINDER);
		boolean noDeliveryInformation = customer.getDeliveryCountry() == null;
		
		//delivery address
		grid.add(new TextPrint("Delivery address:", bold));
	    grid.add(new TextPrint(noDeliveryInformation ? "" : customer.getDeliveryAddress(), normal));
	    
	    //CAP
	    grid.add(new TextPrint("CAP:", bold));
        grid.add(new TextPrint(noDeliveryInformation ? "" : customer.getDeliveryCap(), normal));
	
        //location
        grid.add(new TextPrint("Location:", bold));
        grid.add(new TextPrint(noDeliveryInformation ? "" : customer.getDeliveryLocation(), normal));
	
        //country
        grid.add(new TextPrint("Country:", bold));
        grid.add(new TextPrint(noDeliveryInformation ? "" : customer.getDeliveryCountry().getDescription(), normal));
	
        //header
		grid.add(new TextPrint("\nAdditional information", bold), GridPrint.REMAINDER);
		grid.add(new TextPrint(customer.getNotes(), normal), GridPrint.REMAINDER);
	}

	private static void prepareProductData(Product product, GridPrint grid, FontData bold, FontData normal) {
		//header
		grid.add(new TextPrint("\nProduct information", bold), GridPrint.REMAINDER);
		
        //name
        grid.add(new TextPrint("Name:", bold));
        grid.add(new TextPrint(product.getName(), normal));
        
        //manufacturer
        grid.add(new TextPrint("Manufacturer:", bold));
        grid.add(new TextPrint(product.getManufacturer(), normal));
        
        //available quantity
        grid.add(new TextPrint("Available quantity:", bold));
        grid.add(new TextPrint((product.getAvailableQuantity() == -1) ? "" : String.valueOf(product.getAvailableQuantity()), normal));
        
        //purchasing price
        grid.add(new TextPrint("Purchasing price (Euro):", bold));
        grid.add(new TextPrint((product.getPurchasingPrice() == -1) ? "" : String.valueOf(product.getPurchasingPrice()), normal));
      
		//iva
        grid.add(new TextPrint("Iva (%):", bold));
        grid.add(new TextPrint(String.valueOf(product.getIva()), normal));
        
        //sales price
        grid.add(new TextPrint("Sales price (Euro):", bold));
        grid.add(new TextPrint(String.valueOf(product.getSalesPrice()), normal));
        
        //additional notes
        grid.add(new TextPrint("Additional notes:", bold));
        grid.add(new TextPrint(product.getNotes(), normal));
    }
}
